package com.zhai.service;

import com.zhai.config.RpcConfig;
import com.zhai.invoke.ServiceMethod;
import com.zhai.scan.DubboScanReflect;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.springframework.util.CollectionUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class ServiceHandlerPage extends AbstractHandler {

    private RpcConfig rpcConfig;

    public ServiceHandlerPage(RpcConfig rpcConfig) {
        this.rpcConfig = rpcConfig;
    }

    private final Configuration cfg = new Configuration();

    {
        cfg.setObjectWrapper(new DefaultObjectWrapper());
        ClassTemplateLoader templateLoader = new ClassTemplateLoader(ServiceHandlerPage.class, "/");
        cfg.setTemplateLoader(templateLoader);
    }


    public String getView() {
        return "Service.ftl";
    }

    @Override
    public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, ServletException {
        httpServletResponse.setContentType("text/html; charset=utf-8");
        httpServletResponse.setStatus(HttpServletResponse.SC_OK);

        /**
         * 画页面
         */
        generateView(httpServletRequest, httpServletResponse);

        request.setHandled(true);
    }

    /**
     * freemarker 模板页面展示
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    protected void generateView(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        Template temp = cfg.getTemplate(getView());
        try {
            ServicePage dataModel = this.initData();
            temp.process(dataModel, response.getWriter());
        } catch (TemplateException e) {
            throw new ServletException(e);
        }
    }

    /**
     * 初始话页面数据
     * @return
     */
    protected ServicePage initData() {
        ServicePage dataModel = new ServicePage();
        dataModel.setAppName(rpcConfig.getApplicationName());
        dataModel.setEnvironment("dev");
        dataModel.setGroup(rpcConfig.getProviderGroup());

        //获取反射方法
        List<Service> services = new ArrayList<>();
        List<Class> serviceClassList = DubboScanReflect.getScanClass(rpcConfig.getRpcScanPath());
        if (!CollectionUtils.isEmpty(serviceClassList)) {
            for (Class item : serviceClassList) {
                Service service = new Service();
                List<Method> clazzMethod = DubboScanReflect.getClassMethod(item);
                List<ServiceMethod> serviceMethods = new ArrayList<>();
                if (!CollectionUtils.isEmpty(clazzMethod)) {
                    for (Method m : clazzMethod) {
                        ServiceMethod serviceMethod = new ServiceMethod();
                        serviceMethod.setName(m.getName());
                        serviceMethod.setParameterTypes(m.getParameterTypes());
                        serviceMethod.setReturnType(m.getReturnType());
                        serviceMethods.add(serviceMethod);
                    }
                }
                service.setMethods(serviceMethods);
                service.setName(item.getName());
                service.setType(item);
                //获取类名称
                services.add(service);
            }
        }
        dataModel.setServices(services);
        dataModel.setPort(rpcConfig.getProviderPort());
        String hostAddress = "127.0.0.1";
        try{
            InetAddress ip = InetAddress.getLocalHost();
            hostAddress = ip.getHostAddress();
        }catch (UnknownHostException e){
            e.printStackTrace();
            dataModel.setHost(hostAddress);
            return dataModel;
        }
        return dataModel;
    }
}
